
using System;
using Velocity4Net.Ctx;
using Velocity4Net.Util.Introspection;

namespace Velocity4Net.App.Events
{
    /**
     * Event handler called when an invalid reference is encountered.  Allows 
     * the application to report errors or substitute return values. May be chained
     * in sequence; the behavior will differ per method.
     * 
     * <p>This feature should be regarded as experimental.
     *
     * @author <a href="mailto:wglass@forio.com">Will Glass-Husain</a>
     * @version $Id: InvalidReferenceEventHandler.java 832324 2009-11-03 07:33:03Z wglass $
     * @since 1.5
     */
    public interface InvalidReferenceEventHandler : EventHandler
    {

        /**
         * Called when object is null or there is no getter for the given 
         * property.  Also called for invalid references without properties.  
         * invalidGetMethod() will be called in sequence for
         * each link in the chain until the first non-null value is
         * returned.
         * 
         * @param context the context when the reference was found invalid
         * @param reference string with complete invalid reference. If silent reference, will start with $!
         * @param object the object referred to, or null if not found
         * @param property the property name from the reference
         * @param info contains template, line, column details
         * @return substitute return value for missing reference, or null if no substitute
         */
         Object invalidGetMethod(IContext context, String reference,
                Object _object, String property, Info info);

        /**
         * Called when object is null or there is no setter for the given 
         * property.  invalidSetMethod() will be called in sequence for
         * each link in the chain until a true value is returned.  It's
         * recommended that false be returned as a default to allow
         * for easy chaining.
         * 
         * @param context the context when the reference was found invalid
         * @param leftreference left reference being assigned to
         * @param rightreference invalid reference on the right
         * @param info contains info on template, line, col
         * 
         * @return if true then stop calling invalidSetMethod along the 
         * chain.
         */
         bool invalidSetMethod(IContext context, String leftreference,
                String rightreference, Info info);

        /**
         * Called when object is null or the given method does not exist.
         * invalidMethod() will be called in sequence for each link in 
         * the chain until the first non-null value is returned. 
         * 
         * @param context the context when the reference was found invalid
         * @param reference string with complete invalid reference.  If silent reference, will start with $!
         * @param object the object referred to, or null if not found
         * @param method the name of the (non-existent) method
         * @param info contains template, line, column details
         * @return substitute return value for missing reference, or null if no substitute
         */
         Object invalidMethod(IContext context, String reference,
                Object _object, String method, Info info);


    }
}